package com.iplant.mes.serviceImpl.dao.sfc;

import com.iplant.aps.service.po.aps.APSTaskPartPoint;
import com.iplant.aps.service.po.aps.APSTaskPartPointDay;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.utils.annotation.dao.DBBaseDAO;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.mes.service.po.sfc.SFCTaskSelf;
import com.iplant.pdm.service.basicenum.pdm.PDMComponentTypes;
import com.iplant.pdm.service.po.fpc.FPCProductCom;
import lombok.extern.slf4j.Slf4j;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@DBBaseDAO(SFCTaskSelf.class)
@Slf4j
public class SFCTaskSelfDAO extends BaseDAO {

    private static SFCTaskSelfDAO Instance = null;

    public static SFCTaskSelfDAO getInstance() {
        if (Instance == null) {
            Instance = new SFCTaskSelfDAO();
        }
        return Instance;
    }

    public SFCTaskSelfDAO() {
        super("");
        this.Init();
    }

    /**
     * 维护派工任务的实际执行进度
     */
    public void SFC_UpdatesPlanRealTimeProgress(BMSEmployee wLoginUser, SFCTaskSelf wSFCTaskSelf, Map<Integer,
            List<FPCProductCom>> wProductIDComMap, OutResult<Integer> wErrorCode) {
        try {
            //根据产品组成，获取比例
            float wProportion = 1;
            if (wProductIDComMap.containsKey(wSFCTaskSelf.ProductID)) {
                List<FPCProductCom> wFPCProductComList = wProductIDComMap.get(wSFCTaskSelf.ProductID);

                if (wSFCTaskSelf.ComponentType == PDMComponentTypes.Box.getValue()) {
                    if (wFPCProductComList.stream().anyMatch(p -> p.TargetComponentType == wSFCTaskSelf.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.TargetComponentType == wSFCTaskSelf.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                } else {
                    if (wFPCProductComList.stream().anyMatch(p -> p.ComponentType == wSFCTaskSelf.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.ComponentType == wSFCTaskSelf.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                }
                if (wProportion <= 0) {
                    wProportion = 1;
                }
            }

            String wSQL = "";
            if (wSFCTaskSelf.ComponentType == PDMComponentTypes.Box.getValue()) {
                wSQL = StringUtils.Format("UPDATE {0}.sfc_task_self  " +
                                "SET ActNum = ((SELECT SUM(ActNum) FROM {0}.sfc_task_report WHERE TaskSelfID = " +
                                ":TaskSelfID and Status=2 and IsRepairPlan=0) * :wProportion)  " +
                                "WHERE ID = :TaskSelfID;",
                        DBSchemas.MES.getDBName());
            } else {
                wSQL = StringUtils.Format("UPDATE {0}.sfc_task_self  " +
                                "SET ActNum = ((SELECT SUM(ActNum) FROM {0}.sfc_task_report WHERE TaskSelfID = " +
                                ":TaskSelfID and Status=2 and IsRepairPlan=0) / :wProportion)  " +
                                "WHERE ID = :TaskSelfID;",
                        DBSchemas.MES.getDBName());
            }


            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskSelfID", wSFCTaskSelf.ID);
            wParamMap.put("wProportion", wProportion);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress", ex);
        }
    }

    public void SFC_UpdatesPlanRealTimeProgress_DayPlan(BMSEmployee wLoginUser,
                                                        APSTaskPartPointDay wAPSTaskPartPointDay,
                                                        int wTaskPartPointDayID, Map<Integer
            , List<FPCProductCom>> wProductIDComMap, OutResult<Integer> wErrorCode) {
        try {
            //根据产品组成，获取比例
            float wProportion = 1;
            if (wProductIDComMap.containsKey(wAPSTaskPartPointDay.ProductID)) {
                List<FPCProductCom> wFPCProductComList = wProductIDComMap.get(wAPSTaskPartPointDay.ProductID);

                if (wAPSTaskPartPointDay.ComponentType == PDMComponentTypes.Box.getValue()) {
                    if (wFPCProductComList.stream().anyMatch(p -> p.TargetComponentType == wAPSTaskPartPointDay.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.TargetComponentType == wAPSTaskPartPointDay.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                } else {
                    if (wFPCProductComList.stream().anyMatch(p -> p.ComponentType == wAPSTaskPartPointDay.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.ComponentType == wAPSTaskPartPointDay.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                }
                if (wProportion <= 0) {
                    wProportion = 1;
                }
            }

            String wSQL = "";
            if (wAPSTaskPartPointDay.ComponentType == PDMComponentTypes.Box.getValue()) {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint_day  " +
                                "SET ActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointDayID " +
                                "= " +
                                ":TaskPartPointDayID and Status=2 and IsRepairPlan=0) * :wProportion)  " +
                                "WHERE ID = :TaskPartPointDayID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            } else {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint_day  " +
                                "SET ActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointDayID " +
                                "= " +
                                ":TaskPartPointDayID and Status=2 and IsRepairPlan=0) / :wProportion)  " +
                                "WHERE ID = :TaskPartPointDayID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            }


            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskPartPointDayID", wTaskPartPointDayID);
            wParamMap.put("wProportion", wProportion);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress_DayPlan", ex);
        }
    }

    public void SFC_UpdatesPlanRealTimeProgress_PartPointPlan(BMSEmployee wLoginUser,
                                                              APSTaskPartPoint wAPSTaskPartPoint,
                                                              Map<Integer, List<FPCProductCom>> wProductIDComMap,
                                                              OutResult<Integer> wErrorCode) {
        try {
            //根据产品组成，获取比例
            float wProportion = 1;
            if (wProductIDComMap.containsKey(wAPSTaskPartPoint.ProductID)) {
                List<FPCProductCom> wFPCProductComList = wProductIDComMap.get(wAPSTaskPartPoint.ProductID);

                if (wAPSTaskPartPoint.ComponentType == PDMComponentTypes.Box.getValue()) {
                    if (wFPCProductComList.stream().anyMatch(p -> p.TargetComponentType == wAPSTaskPartPoint.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.TargetComponentType == wAPSTaskPartPoint.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                } else {
                    if (wFPCProductComList.stream().anyMatch(p -> p.ComponentType == wAPSTaskPartPoint.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.ComponentType == wAPSTaskPartPoint.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                }
                if (wProportion <= 0) {
                    wProportion = 1;
                }
            }

            String wSQL = "";
            if (wAPSTaskPartPoint.ComponentType == PDMComponentTypes.Box.getValue()) {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint  " +
                                "SET ActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointID = " +
                                ":TaskPartPointID and Status=2 and IsRepairPlan=0) * :wProportion)  " +
                                "WHERE ID = :TaskPartPointID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            } else {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint  " +
                                "SET ActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointID = " +
                                ":TaskPartPointID and Status=2 and IsRepairPlan=0) / :wProportion)  " +
                                "WHERE ID = :TaskPartPointID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            }


            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskPartPointID", wAPSTaskPartPoint.ID);
            wParamMap.put("wProportion", wProportion);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress_PartPointPlan", ex);
        }
    }

    public void SFC_UpdatesPlanRealTimeProgress_PartPointPlan_His(BMSEmployee wLoginUser, SFCTaskSelf wSFCTaskSelf,
                                                                  Map<Integer, List<FPCProductCom>> wProductIDComMap,
                                                                  Calendar wSTime, OutResult<Integer> wErrorCode) {
        try {
            //根据产品组成，获取比例
            float wProportion = 1;
            if (wProductIDComMap.containsKey(wSFCTaskSelf.ProductID)) {
                List<FPCProductCom> wFPCProductComList = wProductIDComMap.get(wSFCTaskSelf.ProductID);

                if (wSFCTaskSelf.ComponentType == PDMComponentTypes.Box.getValue()) {
                    if (wFPCProductComList.stream().anyMatch(p -> p.TargetComponentType == wSFCTaskSelf.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.TargetComponentType == wSFCTaskSelf.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                } else {
                    if (wFPCProductComList.stream().anyMatch(p -> p.ComponentType == wSFCTaskSelf.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.ComponentType == wSFCTaskSelf.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                }
                if (wProportion <= 0) {
                    wProportion = 1;
                }
            }

            String wSQL = "";
            if (wSFCTaskSelf.ComponentType == PDMComponentTypes.Box.getValue()) {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint  " +
                                "SET HisActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointID " +
                                "= " +
                                ":TaskPartPointID and Status=2 and ConfirmTime<:TodayTime and IsRepairPlan=0) * " +
                                ":wProportion)  " +
                                "WHERE ID = :TaskPartPointID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            } else {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint  " +
                                "SET HisActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointID " +
                                "= " +
                                ":TaskPartPointID and Status=2 and ConfirmTime<:TodayTime and IsRepairPlan=0) / " +
                                ":wProportion)  " +
                                "WHERE ID = :TaskPartPointID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            }

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskPartPointID", wSFCTaskSelf.TaskPartPointID);
            wParamMap.put("wProportion", wProportion);
            wParamMap.put("TodayTime", wSTime);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress_PartPointPlan_His", ex);
        }
    }

    public void SFC_UpdatesPlanRealTimeProgress_PartPointPlan_His(BMSEmployee wLoginUser,
                                                                  APSTaskPartPoint wAPSTaskPartPoint,
                                                                  Map<Integer, List<FPCProductCom>> wProductIDComMap,
                                                                  Calendar wSTime, OutResult<Integer> wErrorCode) {
        try {
            //根据产品组成，获取比例
            float wProportion = 1;
            if (wProductIDComMap.containsKey(wAPSTaskPartPoint.ProductID)) {
                List<FPCProductCom> wFPCProductComList = wProductIDComMap.get(wAPSTaskPartPoint.ProductID);

                if (wAPSTaskPartPoint.ComponentType == PDMComponentTypes.Box.getValue()) {
                    if (wFPCProductComList.stream().anyMatch(p -> p.TargetComponentType == wAPSTaskPartPoint.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.TargetComponentType == wAPSTaskPartPoint.ComponentType && p.ComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                } else {
                    if (wFPCProductComList.stream().anyMatch(p -> p.ComponentType == wAPSTaskPartPoint.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue())) {
                        wProportion =
                                wFPCProductComList.stream().filter(p -> p.ComponentType == wAPSTaskPartPoint.ComponentType && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst().get().ComponentNumber;
                    }
                }
                if (wProportion <= 0) {
                    wProportion = 1;
                }
            }

            String wSQL = "";
            if (wAPSTaskPartPoint.ComponentType == PDMComponentTypes.Box.getValue()) {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint  " +
                                "SET HisActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointID " +
                                "= " +
                                ":TaskPartPointID and Status=2 and ConfirmTime<:TodayTime and IsRepairPlan=0) * " +
                                ":wProportion)  " +
                                "WHERE ID = :TaskPartPointID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            } else {
                wSQL = StringUtils.Format("UPDATE {0}.aps_task_partpoint  " +
                                "SET HisActNum = ((SELECT SUM(ActNum) FROM {1}.sfc_task_report WHERE TaskPartPointID " +
                                "= " +
                                ":TaskPartPointID and Status=2 and ConfirmTime<:TodayTime and IsRepairPlan=0) / " +
                                ":wProportion)  " +
                                "WHERE ID = :TaskPartPointID;",
                        DBSchemas.APS.getDBName(), DBSchemas.MES.getDBName());
            }

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskPartPointID", wAPSTaskPartPoint.ID);
            wParamMap.put("wProportion", wProportion);
            wParamMap.put("TodayTime", wSTime);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress_PartPointPlan_His", ex);
        }
    }

    public void SFC_UpdatesPlanRealTimeProgress_WeekPlan(BMSEmployee wLoginUser, SFCTaskSelf wSFCTaskSelf,
                                                         OutResult<Integer> wErrorCode) {
        try {
            String wSQL = StringUtils.Format("UPDATE {0}.aps_task_part  " +
                            "SET ActNum = (SELECT ActNum FROM {0}.aps_task_partpoint WHERE ID = " +
                            ":TaskPartPointID )  " +
                            "WHERE ID = :TaskPartID;",
                    DBSchemas.APS.getDBName());

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskPartPointID", wSFCTaskSelf.TaskPartPointID);
            wParamMap.put("TaskPartID", wSFCTaskSelf.TaskPartID);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress_WeekPlan", ex);
        }
    }

    public void SFC_UpdatesPlanRealTimeProgress_MonthPlan(BMSEmployee wLoginUser, SFCTaskSelf wSFCTaskSelf,
                                                          OutResult<Integer> wErrorCode) {
        try {
            String wSQL = StringUtils.Format("UPDATE {0}.aps_task_part  " +
                            "SET ActNum = (SELECT ActNum FROM {0}.aps_task_partpoint WHERE ID = " +
                            ":TaskPartPointID )  " +
                            "WHERE OrderID=:OrderID and RoutePartID=:RoutePartID and Active=1 and ShiftPeriod=6;",
                    DBSchemas.APS.getDBName());

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("TaskPartPointID", wSFCTaskSelf.TaskPartPointID);
            wParamMap.put("OrderID", wSFCTaskSelf.OrderID);
            wParamMap.put("RoutePartID", wSFCTaskSelf.RoutePartID);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error("SFC_UpdatesPlanRealTimeProgress_MonthPlan", ex);
        }
    }

    /**
     * 根据ID删除派工单
     */
    public void SFC_DeleteTaskSelf(BMSEmployee wLoginUser, SFCTaskSelf wSFCTaskSelf, OutResult<Integer> wErrorCode) {
        try {
            String wSQL = StringUtils.Format("DELETE FROM {0}.`sfc_task_self` WHERE ID=:ID;",
                    DBSchemas.MES.getDBName());

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wParamMap.put("ID", wSFCTaskSelf.ID);

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            log.error(ex.toString());
        }
    }
}
